#ifndef __AVOS_LIST_H_
#define __AVOS_LIST_H_

/**
 * Returns container address by member address and type definition
 * TODO: move it to a separate header
 */
#define container_of(ptr, type, member)	\
	((type *) ((char *)(ptr) - (unsigned long)(&((type *)0)->member)))

/**
 * Doubly linked list implementation. 
 */
typedef struct list_head {
	struct list_head *next, *prev;
} list_t;

/**
 * Return entry containing the list_t
 */
#define list_entry(list, type, member)	\
	container_of(list, type, member)

/**
 * Initialize list so that it would link to itself
 */
static inline void list_init(list_t *head)
{
	head->next = head;
	head->prev = head;
}

/**
 * Add item to the list head
 */
static inline void list_add(list_t *head, list_t *new)
{
	head->next->prev = new;
	new->next = head->next;
	new->prev = head;
	head->next = new;
}

/**
 * Add item to the list tail
 */
static inline void list_add_tail(list_t *head, list_t *new)
{
	head->prev->next = new;
	new->next = head;
	new->prev = head->prev;
	head->prev = new;
}

/**
 * Delete entry from the list
 */
static inline void list_del(list_t *entry)
{
	entry->prev->next = entry->next;
	entry->next->prev = entry->prev;

	/* TODO: Invalidate old item? */
	/* entry->next = entry->prev = 0xdeadf00d; */
}

/**
 * Replace one list item with another one
 */
static inline void list_replace(list_t *old, list_t *new)
{
	new->next = old->next;
	new->next->prev = new;
	new->prev = old->prev;
	new->prev->next = new;
	/* TODO: Invalidate old item? */
}

/**
 * Get the first item from list
 */
#define list_first(list, type, member)	\
	list_entry((list)->next, type, member)

/**
 * Get list item from list
 */
#define list_last(list, type, member)	\
	list_entry((list)->prev, type, member)

/**
 * Returns zero if list is not empty and nonzero otherwise
 */
static inline int list_empty(list_t *head)
{
	return (head->next == head);
}

/**
 * Iterate list forward
 */
#define list_for_each(head, pos) \
	for (pos = (head)->next; pos->next, pos != (head); \
        	pos = pos->next)

/**
 * Safe iterate list
 */
#define list_for_each_safe(head, pos, n) \
	for (pos = (head)->next, n = pos->next; pos != (head); \
		pos = n, n = pos->next)

#endif /* __AVOS_LIST_H_ */
